home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / moni / systemviewer.lha / SysHardware.c < prev    next >
C/C++ Source or Header  |  2001-04-25  |  16KB  |  668 lines

  1. /****h* SysHardware/SysHardware.c [1.1] *****************************
  2. *
  3. * NAME
  4. *    SysHardware.c
  5. *
  6. * DESCRIPTION
  7. *    Display some information about the Amiga Hardware found.
  8. *
  9. * NOTES
  10. *    $VER: SysHardware.c 1.1 (25-Apr-2001) by J.T. Steichen
  11. *********************************************************************
  12. *
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17.  
  18. #include <exec/types.h>
  19. #include <exec/execbase.h>
  20.  
  21. #include <AmigaDOSErrs.h>
  22.  
  23. #include <dos/dosextens.h>
  24.  
  25. #include <intuition/intuition.h>
  26. #include <intuition/classes.h>
  27. #include <intuition/classusr.h>
  28. #include <intuition/gadgetclass.h>
  29.  
  30. #include <libraries/gadtools.h>
  31. #include <libraries/expansion.h>
  32. #include <libraries/expansionbase.h>
  33.  
  34. #include <graphics/displayinfo.h>
  35. #include <graphics/gfxbase.h>
  36.  
  37. #include <clib/exec_protos.h>
  38. #include <clib/intuition_protos.h>
  39. #include <clib/gadtools_protos.h>
  40. #include <clib/graphics_protos.h>
  41. #include <clib/utility_protos.h>
  42. #include <clib/diskfont_protos.h>
  43.  
  44. #include "CPGM:GlobalObjects/CommonFuncs.h"
  45.  
  46. #include "SysLists.h"
  47.  
  48. #define HLV     0
  49. #define Cancel  1
  50.  
  51. #define ATS_CNT 2
  52.  
  53. IMPORT  struct ExecBase *SysBase; // GfxBase in SysLists.h
  54.  
  55. PRIVATE struct ExpansionBase *ExpansionBase;
  56.  
  57. PRIVATE char vr[] = "\0$VER: SysHardware 1.1 (25-Apr-2001) by J.T. Steichen\0";
  58.  
  59. PRIVATE struct TextFont *ATSFont  = NULL;
  60. PRIVATE struct Window   *ATSWnd   = NULL;
  61. PRIVATE struct Gadget   *ATSGList = NULL;
  62. PRIVATE struct Gadget   *ATSGadgets[ ATS_CNT ];
  63.  
  64. PRIVATE struct IntuiMessage  ATSMsg;
  65.  
  66. PRIVATE UWORD  ATSLeft   = 0;
  67. PRIVATE UWORD  ATSTop    = 16;
  68. PRIVATE UWORD  ATSWidth  = 640;
  69. PRIVATE UWORD  ATSHeight = 270;
  70. PRIVATE UBYTE *ATSWdt    = (UBYTE *) "System Hardware Info:";
  71.  
  72. PRIVATE UBYTE *ttl = "Brd.Addr: Brd.Size: Mfg-ID: Prod: Driver: Flags:    S/N: DiagVec:  Type:";
  73.  
  74. PRIVATE char fmt[] = "$%08LX $%08LX %5d %5d   %-3.3s     $%08LX  %d   $%08LX %d";
  75.  
  76. // ----------------------------------------------------------------------
  77.  
  78. #define MAXHVNODES 26
  79. #define NODELENGTH 80
  80.  
  81. PRIVATE struct Node HLVNodes[ MAXHVNODES ] = { 0, };
  82.  
  83. PRIVATE struct List HLVList = { 0, };
  84.  
  85. PRIVATE UBYTE NodeStrs[ MAXHVNODES * NODELENGTH ] = ""; 
  86.  
  87. PRIVATE struct ListViewMem lvm = { 0, };
  88.     
  89. // ----------------------------------------------------------------------
  90.  
  91. PRIVATE int HLVClicked(    void );
  92. PRIVATE int CancelClicked( void );
  93.  
  94. PRIVATE struct NewGadget ATSNGad[] = {
  95.  
  96.      2,   3, 627, 250,                NULL, NULL, HLV, 
  97.    0, NULL, (APTR) HLVClicked,
  98.  
  99.    295, 250,  72,  17, (UBYTE *) "_Cancel", NULL, Cancel, 
  100.    PLACETEXT_IN, NULL, (APTR) CancelClicked
  101.  
  102. };
  103.  
  104. PRIVATE ULONG ATSGTags[] = {
  105.  
  106.    GTLV_ReadOnly, TRUE, GTLV_ShowSelected, NULL,
  107.    LAYOUTA_Spacing, 2, TAG_DONE,
  108.    
  109.    GT_Underscore, '_', TAG_DONE
  110. };
  111.  
  112. PRIVATE UWORD ATSGTypes[] = { LISTVIEW_KIND, BUTTON_KIND };
  113.  
  114. // ----------------------------------------------------------------------
  115.  
  116. SUBFUNC char *GetProcType( void )
  117. {
  118.    if ((SysBase->AttnFlags & AFF_68060) == AFF_68060)
  119.       return( "68060" );
  120.  
  121.    if ((SysBase->AttnFlags & AFF_68040) == AFF_68040)
  122.       return( "68040" );
  123.  
  124.    if ((SysBase->AttnFlags & AFF_68030) == AFF_68030)
  125.       return( "68030" );
  126.  
  127.    if ((SysBase->AttnFlags & AFF_68020) == AFF_68020)
  128.       return( "68020" );
  129.  
  130.    if ((SysBase->AttnFlags & AFF_68010) == AFF_68010)
  131.       return( "68010" );
  132.    else
  133.       return( "68000" );
  134. }
  135.  
  136. SUBFUNC char *GetFPUType( void )
  137. {
  138.    if ((SysBase->AttnFlags & AFF_FPU40) == AFF_FPU40)
  139.       {
  140.       if ((SysBase->AttnFlags & AFF_68040) == AFF_68040)
  141.          return( "68882 (68040 FPU)" );
  142.       else
  143.          return( "NONE" );
  144.       }
  145.  
  146.    if ((SysBase->AttnFlags & AFF_68882) == AFF_68882)
  147.       return( "68882" );
  148.  
  149.    if ((SysBase->AttnFlags & AFF_68881) == AFF_68881)
  150.       return( "68881" );
  151.    else
  152.       return( "NONE" );
  153. }
  154.  
  155. SUBFUNC char *GetInstCache( void )
  156. {
  157.    IMPORT int GetCacheReg( void );
  158.  
  159.    ULONG result = Supervisor( (void *) GetCacheReg );
  160.  
  161. //   fprintf( stderr, "GetCacheReg() returned 0x%08LX\n", result );
  162.  
  163.    if ((result & 0x00008000) == 0x00008000) // bit 15 of CACR set??
  164.       return( "ON" );
  165.    else
  166.       return( "OFF" );
  167. }
  168.  
  169. SUBFUNC char *GetDataCache( void )
  170. {
  171.    IMPORT int GetCacheReg( void );
  172.  
  173.    ULONG result = Supervisor( (void *) GetCacheReg );
  174.  
  175. //   fprintf( stderr, "GetCacheReg() returned 0x%08LX\n", result );
  176.  
  177.    if ((result & 0x80000000) == 0x80000000) // bit 31 of CACR set??
  178.       return( "ON" );
  179.    else
  180.       return( "OFF" );
  181. }
  182.  
  183. SUBFUNC char *GetBurstCache( void )
  184. {
  185.    IMPORT int GetMMUsrReg( void );
  186.  
  187.    ULONG result = Supervisor( (void *) GetMMUsrReg );
  188.  
  189. //   fprintf( stderr, "GetMMUsrReg() returned 0x%08LX\n", result );
  190.  
  191.    if ((result & 0x00000060) == 0x00000040) // burst mode??
  192.       return( "ON" );
  193.    else
  194.       return( "OFF" );
  195. }
  196.  
  197. SUBFUNC char *GetCopyBackCache( void )
  198. {
  199.    IMPORT int GetMMUsrReg( void );
  200.  
  201.    ULONG result = Supervisor( (void *) GetMMUsrReg );
  202.  
  203. //   fprintf( stderr, "GetMMUsrReg() returned 0x%08LX\n", result );
  204.  
  205.    if ((result & 0x00000060) == 0x00000020) // CopyBack mode??
  206.       return( "ON" );
  207.    else
  208.       return( "OFF" );
  209. }
  210.  
  211. // Stuff from GfxBase:
  212.  
  213. SUBFUNC char *GetDMACustomName( void )
  214. {
  215.    if ((GfxBase->ChipRevBits0 & GFXF_AA_ALICE) == GFXF_AA_ALICE)
  216.       return( "Alice" );
  217.  
  218.    if ((GfxBase->ChipRevBits0 & GFXF_HR_AGNUS) == GFXF_HR_AGNUS)
  219.       return( "Agnus" );
  220.    else
  221.       return( "Agnus" );
  222. }
  223.  
  224. SUBFUNC char *GetGraphicCustomName( void )
  225. {
  226.    if ((GfxBase->ChipRevBits0 & GFXF_AA_MLISA) == GFXF_AA_MLISA)
  227.       return( "MLisa" );
  228.  
  229.    if ((GfxBase->ChipRevBits0 & GFXF_AA_LISA) == GFXF_AA_LISA)
  230.       return( "Lisa" );
  231.  
  232.    if ((GfxBase->ChipRevBits0 & GFXF_HR_DENISE) == GFXF_HR_DENISE)
  233.       return( "Denise" );
  234.    else
  235.       return( "Denise" );
  236. }
  237.  
  238. SUBFUNC char *GetVideoType( void )
  239. {
  240.    if ((GfxBase->DisplayFlags & NTSC) == NTSC)
  241.       return( "NTSC" );
  242.  
  243.    if ((GfxBase->DisplayFlags & PAL) == PAL)
  244.       return( "PAL" );
  245.  
  246.    if ((GfxBase->DisplayFlags & GENLOCK) == GENLOCK)
  247.       return( "GENLOCK" );
  248.    else
  249.       return( "NTSC" );
  250. }
  251.  
  252. // Version info:
  253.  
  254. PRIVATE char wbv[24];
  255.  
  256. SUBFUNC char *GetWorkbenchVersion( void )
  257. {
  258.    struct Library *wbenchbase = NULL;
  259.    
  260.    if ((wbenchbase = OpenLibrary( "workbench.library", 0L )) == NULL)
  261.       return( "Unable to open!" );
  262.  
  263.    sprintf( wbv, "%d.%d", 
  264.                  wbenchbase->lib_Version, 
  265.                  wbenchbase->lib_Revision 
  266.           );
  267.  
  268.    CloseLibrary( wbenchbase );
  269.  
  270.    return( &wbv[0] );
  271. }
  272.  
  273. PRIVATE char exv[24];
  274.  
  275. SUBFUNC char *GetExecVersion( void )
  276. {
  277.    sprintf( exv, "%d.%d", SysBase->LibNode.lib_Version,
  278.                           SysBase->LibNode.lib_Revision
  279.           ); 
  280.  
  281.    return( &exv[0] );
  282. }
  283.  
  284. PRIVATE char dosv[24];
  285.  
  286. SUBFUNC char *GetDosVersion( void )
  287. {
  288.    struct DosLibrary *dosbase = NULL; // <dos/dosextens.h>
  289.    
  290.    if ((dosbase = (struct DosLibrary *)
  291.                   OpenLibrary( "dos.library", 0L )) == NULL)
  292.       return( "Unable to open!" );
  293.  
  294.    sprintf( dosv, "%d.%d", 
  295.                  dosbase->dl_lib.lib_Version, 
  296.                  dosbase->dl_lib.lib_Revision 
  297.           );
  298.  
  299.    CloseLibrary( (struct Library *) dosbase );
  300.  
  301.    return( &dosv[0] );
  302. }
  303.  
  304. SUBFUNC int WriteBoardInfo( void )
  305. {
  306.    struct ConfigDev *cd = NULL;
  307.    int                i = 1;
  308.    
  309.    if ((ExpansionBase = (struct ExpansionBase *) 
  310.                         OpenLibrary( EXPANSIONNAME, 0 )) == NULL)
  311.       {
  312.       printf( "Couldn't open %s!\n", EXPANSIONNAME );
  313.       return( -1 );
  314.       }
  315.  
  316.    while (((cd = FindConfigDev( cd, -1, -1 )) != 0) && (i < MAXHVNODES))
  317.       {
  318.       sprintf( &NodeStrs[ i * NODELENGTH ], &fmt[0],
  319.                cd->cd_BoardAddr,
  320.                cd->cd_BoardSize,
  321.                cd->cd_Rom.er_Manufacturer,
  322.                cd->cd_Rom.er_Product,
  323.                cd->cd_Driver == 0 ? "NO" : "YES", 
  324.                cd->cd_Rom.er_Flags,
  325.                cd->cd_Rom.er_SerialNumber,
  326.                cd->cd_Rom.er_InitDiagVec,
  327.                cd->cd_Rom.er_Type 
  328.              );
  329.  
  330.       i++;
  331.       }
  332.  
  333.    CloseLibrary( (struct Library *) ExpansionBase );
  334.  
  335.    return( i ); // Other stuff will be added to the nodes.
  336. }
  337.  
  338. PRIVATE int SetupHardwareLV( void )
  339. {
  340.    int i = WriteBoardInfo();
  341.       
  342.    if (i < 0)
  343.       i = 3;
  344.  
  345.    if (i >= MAXHVNODES - 12)
  346.       {
  347.       return( 0 );
  348.       }
  349.  
  350.    i++;
  351.  
  352.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  353.             "Processor -----------: %s", GetProcType()   
  354.           );
  355.  
  356.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  357.             "Math --- Co-Processor: %s", GetFPUType()    
  358.           );
  359.  
  360.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  361.             "CPU Instruction Cache: %s", GetInstCache()  
  362.           );
  363.  
  364.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  365.             "CPU Instruction Burst: %s", GetBurstCache() 
  366.           );
  367.  
  368.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  369.             "CPU Data ------ Cache: %s", GetDataCache()  
  370.           );
  371.  
  372.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  373.             "CPU Data ------ Burst: %s", GetBurstCache() 
  374.           );
  375.  
  376.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  377.             "CPU -------- CopyBack: %s", GetCopyBackCache() 
  378.           );
  379.  
  380.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  381.             "DMA ----- Custom Chip: %s (%s)", GetDMACustomName(),
  382.                                               GetVideoType()
  383.           );
  384.  
  385.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  386.             "Graphic   Custom Chip: %s", GetGraphicCustomName() 
  387.           );
  388.  
  389.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  390.             "WorkBench     Version: %s", GetWorkbenchVersion()
  391.           );   
  392.  
  393.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  394.             "Exec          Version: %s", GetExecVersion() 
  395.           );
  396.  
  397.    sprintf( &NodeStrs[ i++ * NODELENGTH ],
  398.             "Dos           Version: %s", GetDosVersion() 
  399.           );   
  400.       
  401.    return( 0 );
  402. }
  403.  
  404. // ----------------------------------------------------------------------
  405.  
  406. PRIVATE int OpenATSWindow( void )
  407. {
  408.    struct NewGadget  ng;
  409.    struct Gadget    *g;
  410.    UWORD             lc, tc;
  411.    UWORD             wleft = ATSLeft, wtop = ATSTop, ww, wh;
  412.  
  413.    ComputeFont( Scr, Font, &CFont, ATSWidth, ATSHeight );
  414.  
  415.    ww = ComputeX( CFont.FontX, ATSWidth  );
  416.    wh = ComputeY( CFont.FontY, ATSHeight );
  417.  
  418.    if ((wleft + ww + CFont.OffX + Scr->WBorRight) > Scr->Width)
  419.       wleft = Scr->Width - ww;
  420.  
  421.    if ((wtop + wh + CFont.OffY + Scr->WBorBottom) > Scr->Height)
  422.       wtop = Scr->Height - wh;
  423.  
  424.    if ((ATSFont = OpenDiskFont( Font )) == NULL)
  425.       return( -5 );
  426.  
  427.    if ((g = CreateContext( &ATSGList )) == NULL)
  428.       return( -1 );
  429.  
  430.    for (lc = 0, tc = 0; lc < ATS_CNT; lc++)
  431.       {
  432.       CopyMem( (char *) &ATSNGad[lc], (char *) &ng, 
  433.                (long) sizeof( struct NewGadget )
  434.              );
  435.  
  436.       ng.ng_VisualInfo = VisualInfo;
  437.       ng.ng_TextAttr   = Font;
  438.  
  439.       ng.ng_LeftEdge   = CFont.OffX + ComputeX( CFont.FontX, 
  440.                                                 ng.ng_LeftEdge
  441.                                               );
  442.  
  443.       ng.ng_TopEdge    = CFont.OffY + ComputeY( CFont.FontY, 
  444.                                                 ng.ng_TopEdge
  445.                                               );
  446.  
  447.       ng.ng_Width      = ComputeX( CFont.FontX, ng.ng_Width );
  448.       ng.ng_Height     = ComputeY( CFont.FontY, ng.ng_Height );
  449.  
  450.       ATSGadgets[lc] = g 
  451.                      = CreateGadgetA( (ULONG) ATSGTypes[lc], 
  452.                                       g, 
  453.                                       &ng, 
  454.                                       (struct TagItem *) &ATSGTags[tc]
  455.                                     );
  456.  
  457.       while (ATSGTags[tc] != TAG_DONE)
  458.          tc += 2;
  459.  
  460.       tc++;
  461.  
  462.       if (g == NULL)
  463.          return( -2 );
  464.       }
  465.  
  466.    if ((ATSWnd = OpenWindowTags( NULL,
  467.  
  468.                   WA_Left,        wleft,
  469.                   WA_Top,         wtop,
  470.                   WA_Width,       ww + CFont.OffX + Scr->WBorRight,
  471.                   WA_Height,      wh + CFont.OffY + Scr->WBorBottom,
  472.                   
  473.                   WA_IDCMP,       LISTVIEWIDCMP | BUTTONIDCMP 
  474.                     | IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW 
  475.                     | IDCMP_VANILLAKEY,
  476.                   
  477.                   WA_Flags,       WFLG_DRAGBAR | WFLG_DEPTHGADGET 
  478.                     | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH 
  479.                     | WFLG_ACTIVATE | WFLG_RMBTRAP,
  480.                   
  481.                   WA_Gadgets,     ATSGList,
  482.                   WA_Title,       ATSWdt,
  483.                   WA_ScreenTitle, "System Hardware Info:",
  484.                   TAG_DONE )
  485.       ) == NULL)
  486.       return( -4 );
  487.  
  488.    GT_RefreshWindow( ATSWnd, NULL );
  489.  
  490.    return( 0 );
  491. }
  492.  
  493. PRIVATE void CloseATSWindow( void )
  494. {
  495.    if (ATSWnd != NULL)
  496.       {
  497.       CloseWindow( ATSWnd );
  498.       ATSWnd = NULL;
  499.       }
  500.  
  501.    if (ATSGList != NULL)
  502.       {
  503.       FreeGadgets( ATSGList );
  504.       ATSGList = NULL;
  505.       }
  506.  
  507.    if (ATSFont != NULL)
  508.       {
  509.       CloseFont( ATSFont );
  510.       ATSFont = NULL;
  511.       }
  512.  
  513.    return;
  514. }
  515.  
  516. PRIVATE int ATSCloseWindow( void )
  517. {
  518.    CloseATSWindow();
  519.    return( FALSE );
  520. }
  521.  
  522. PRIVATE int HLVClicked( void )
  523. {
  524.    // Nothing to do here:
  525.    return( TRUE );
  526. }
  527.  
  528. PRIVATE int CancelClicked( void )
  529. {
  530.    return( ATSCloseWindow() );
  531. }
  532.  
  533. PRIVATE int ATSVanillaKey( int whichkey )
  534. {
  535.    int rval = TRUE;
  536.    
  537.    switch (whichkey)
  538.       {
  539.       case 'c':
  540.       case 'C':
  541.          rval = CancelClicked();
  542.          break;
  543.          
  544.       case 'q':
  545.       case 'Q':
  546.       case 'x':
  547.       case 'X':
  548.          rval = FALSE;
  549.          break;
  550.       }
  551.       
  552.    return( rval );
  553. }
  554.  
  555. PRIVATE int HandleATSIDCMP( void )
  556. {
  557.    struct IntuiMessage  *m;
  558.    int                 (*func)( void );
  559.    BOOL                  running = TRUE;
  560.  
  561.    while (running == TRUE)
  562.       {
  563.       if ((m = GT_GetIMsg( ATSWnd->UserPort )) == NULL)
  564.          {
  565.          (void) Wait( 1L << ATSWnd->UserPort->mp_SigBit );
  566.          continue;
  567.          }
  568.  
  569.       CopyMem( (char *) m, (char *) &ATSMsg, 
  570.                (long) sizeof( struct IntuiMessage )
  571.              );
  572.  
  573.       GT_ReplyIMsg( m );
  574.  
  575.       switch (ATSMsg.Class)
  576.          {
  577.          case IDCMP_REFRESHWINDOW:
  578.             GT_BeginRefresh( ATSWnd );
  579.             GT_EndRefresh( ATSWnd, TRUE );
  580.             break;
  581.  
  582.          case IDCMP_CLOSEWINDOW:
  583.             running = ATSCloseWindow();
  584.             break;
  585.  
  586.          case IDCMP_VANILLAKEY:
  587.             running = ATSVanillaKey( ATSMsg.Code );
  588.             break;
  589.  
  590.          case IDCMP_GADGETUP:
  591.          case IDCMP_GADGETDOWN:
  592.             func = (void *) ((struct Gadget *) ATSMsg.IAddress)->UserData;
  593.             
  594.             if (func != NULL)
  595.                running = func();
  596.  
  597.             break;
  598.          }
  599.       }
  600.  
  601.    return( running );
  602. }
  603.  
  604. PRIVATE int HandleHardware( void )
  605. {
  606.    struct Node ttlNode = { 0, };
  607.    int               i = 0;
  608.     
  609.    // Open Libraries, Screen & Window:
  610.    if (SetupSystemList( &OpenATSWindow ) < 0)
  611.       {
  612.       fprintf( stderr, "Couldn't open a System ListViewer!\n" );
  613.       return( -1 );
  614.       }
  615.    
  616.    SetNotifyWindow( ATSWnd );
  617.  
  618.    DisplayTitle( ATSWnd, "Initializing list..." );
  619.    
  620.    lvm.lvm_NodeStrs   = &NodeStrs[0];
  621.    lvm.lvm_Nodes      = &HLVNodes[0];
  622.    lvm.lvm_NumItems   = MAXHVNODES;
  623.    lvm.lvm_NodeLength = NODELENGTH;
  624.  
  625.    SetupList( &HLVList, &lvm );   
  626.  
  627.    strcpy( HLVNodes[0].ln_Name, ttl );
  628.  
  629.    HideListFromView( ATSGadgets[ HLV ], ATSWnd );
  630.  
  631.    (void) SetupHardwareLV(); // Make the list.
  632.  
  633.    ModifyListView( ATSGadgets[ HLV ], ATSWnd, 
  634.                    (struct List *) &HLVList, NULL
  635.                  );
  636.  
  637.    DisplayTitle( ATSWnd, ATSWdt );
  638.    
  639.    GT_RefreshWindow( ATSWnd, NULL );
  640.  
  641.    (void) HandleATSIDCMP();
  642.    
  643.    // Close Libraries, Screen & Window:
  644.    ShutdownSystemList();
  645.  
  646.    return( 0 );
  647. }
  648.  
  649. PUBLIC int ShowHardware( void )
  650. {
  651.    int rval = 0;
  652.  
  653.    rval = HandleHardware();
  654.    
  655.    return( rval );
  656. }
  657.  
  658. #ifdef DEBUG
  659.  
  660. PUBLIC int main( void )
  661. {
  662.    return( ShowHardware() );
  663. }
  664.  
  665. #endif
  666.  
  667. /* -------------------- END of SysHardware.c file! ------------------ */
  668.